package com.atguigu.ssyx.payment.service.impl;

import com.atguigu.ssyx.common.constant.RedisConst;
import com.atguigu.ssyx.model.order.PaymentInfo;
import com.atguigu.ssyx.payment.service.PaymentInfoService;
import com.atguigu.ssyx.payment.service.WeixinService;
import com.atguigu.ssyx.payment.utils.ConstantPropertiesUtils;
import com.atguigu.ssyx.payment.utils.HttpClient;
import com.atguigu.ssyx.vo.user.UserLoginVo;
import com.github.wxpay.sdk.WXPayUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.Executor;
import java.util.concurrent.TimeUnit;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

/**
 * @作者:胡树苑
 * @时间:2025/9/25 05:08
 */
@Service
@Slf4j
@EnableAsync
public class WeixinServiceImpl implements WeixinService {
    @Autowired
    private PaymentInfoService paymentInfoService;
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private ConstantPropertiesUtils constantPropertiesUtils;
    

    //调用微信系统生成预付单
    @Override
    public Map<String, String> createJsapi(String orderNo) {
        //1 向payment_info支付记录表添加记录，目前支付状态，正在支付中
       PaymentInfo paymentInfo=paymentInfoService.getPayMentInfoByOrderNo(orderNo);
       if(paymentInfo==null){
           paymentInfo=paymentInfoService.savePaymentInfo(orderNo);
       }
       //2.封装微信支付系统需要的参数
        Map<String,String> paramMap=new HashMap<>();
        //1、设置参数
        paramMap.put("appid", constantPropertiesUtils.getAppid());
        paramMap.put("mch_id", constantPropertiesUtils.getPartner());
        paramMap.put("nonce_str", WXPayUtil.generateNonceStr());
        paramMap.put("body", paymentInfo.getSubject());
        paramMap.put("out_trade_no", paymentInfo.getOrderNo());
        int totalFee = paymentInfo.getTotalAmount().multiply(new BigDecimal(100)).intValue();
        paramMap.put("total_fee", String.valueOf(totalFee));
        paramMap.put("spbill_create_ip", "127.0.0.1");
        paramMap.put("notify_url", constantPropertiesUtils.getNotifyurl());
        paramMap.put("trade_type", "JSAPI");
        //openid
        UserLoginVo userLoginVo=(UserLoginVo) redisTemplate.opsForValue()
                .get(RedisConst.USER_LOGIN_KEY_PREFIX+paymentInfo.getUserId());
        if(null != userLoginVo && !StringUtils.isEmpty(userLoginVo.getOpenId())) {
            paramMap.put("openid", userLoginVo.getOpenId());
        } else {
            paramMap.put("openid", "oD7av4igt-00GI8PqsIlg5FROYnI");
        }
        //3.使用HttpClient调用微信支付系统接口
        HttpClient client = new HttpClient("https://api.mch.weixin.qq.com/pay/unifiedorder");


        try {
            //设置参数 xml格式
            client.setXmlParam(WXPayUtil.generateSignedXml(paramMap,constantPropertiesUtils.getPartnerkey()));
            client.setHttps(true);
            client.post();
            //4.调用微信支付系统接口之后，返回结果 prepay_id
            String xml = client.getContent();
            System.out.println("=== 微信支付API响应 ===");
            System.out.println("XML响应: " + xml);
            Map<String, String> resultMap = WXPayUtil.xmlToMap(xml);
            System.out.println("解析后的Map: " + resultMap);
            //5.封装需要的数据包含预支付单标识  prepay_id
            //4、再次封装参数
            Map<String, String> parameterMap = new HashMap<>();
            String prepayId = String.valueOf(resultMap.get("prepay_id"));
            String packages = "prepay_id=" + prepayId;
            parameterMap.put("appId", constantPropertiesUtils.getAppid());
            parameterMap.put("nonceStr", resultMap.get("nonce_str"));
            parameterMap.put("package", packages);
            parameterMap.put("signType", "MD5");
            parameterMap.put("timeStamp", String.valueOf(new Date().getTime()));
            
            // 调试输出
            System.out.println("=== parameterMap 内容 ===");
            for (Map.Entry<String, String> entry : parameterMap.entrySet()) {
                System.out.println(entry.getKey() + " = " + entry.getValue());
            }
            System.out.println("partnerkey = " + constantPropertiesUtils.getPartnerkey());
            
            // 检查微信支付配置是否加载成功
            if (constantPropertiesUtils.getPartnerkey() == null || constantPropertiesUtils.getPartnerkey().isEmpty()) {
                throw new RuntimeException("微信支付配置未正确加载，请检查支付服务是否启动");
            }
            String sign = WXPayUtil.generateSignature(parameterMap, constantPropertiesUtils.getPartnerkey());


            //返回结果
            Map<String, String> result = new HashMap<>();
            result.put("timeStamp", parameterMap.get("timeStamp"));
            result.put("nonceStr", parameterMap.get("nonceStr"));
            result.put("signType", "MD5");
            result.put("paySign", sign);
            result.put("package", packages);
            if(null != resultMap.get("result_code")) {
                //微信支付二维码2小时过期，可采取2小时未支付取消订单
                redisTemplate.opsForValue().set(orderNo, result, 10, TimeUnit.MINUTES);
            }
            
            return result;
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
    
    //1.调用微信支付系统接口查询订单支付状态
    @Override
    public Map<String, String> queryPayStatus(String orderNo) {

            //1、封装参数
            Map<String, String> paramMap = new HashMap<>();
            paramMap.put("appid", ConstantPropertiesUtils.APPID);
            paramMap.put("mch_id", ConstantPropertiesUtils.PARTNER);
            paramMap.put("out_trade_no", orderNo);
            paramMap.put("nonce_str", WXPayUtil.generateNonceStr());

            //2、设置请求
            HttpClient client = new HttpClient("https://api.mch.weixin.qq.com/pay/orderquery");
            try {
            client.setXmlParam(WXPayUtil.generateSignedXml(paramMap, ConstantPropertiesUtils.PARTNERKEY));
            client.setHttps(true);
            client.post();
            //3、返回第三方的数据
            String xml = client.getContent();
            Map<String, String> resultMap = WXPayUtil.xmlToMap(xml);
            //6、转成Map
            //7、返回
            return resultMap;
        } catch (Exception e) {
           throw new RuntimeException(e);
        }
    }
}
